Skip to content

[refactor][java] Improve docs and code quality about KeyValueSchema usages - #17256

Merged
codelipenghui merged 2 commits into
apache:masterfrom
BewareMyPower:bewaremypower/key-value-simplify
Nov 16, 2022
Merged

[refactor][java] Improve docs and code quality about KeyValueSchema usages#17256
codelipenghui merged 2 commits into
apache:masterfrom
BewareMyPower:bewaremypower/key-value-simplify

Conversation

@BewareMyPower

@BewareMyPower BewareMyPower commented Aug 24, 2022

Copy link
Copy Markdown
Contributor

Motivation

First, it's hard to know the default encoding type of a KeyValue schema
from the API and its JavaDocs, see

/**
* Key Value Schema using passed in key and value schemas.
*/
static <K, V> Schema<KeyValue<K, V>> KeyValue(Schema<K> key, Schema<V> value) {
return DefaultImplementation.getDefaultImplementation().newKeyValueSchema(key, value);
}

The default encoding type could only be found in KeyValueSchemaImpl#of
method from another module (pulsar-client).

Second, there are much raw use of parameterized class, including
KeyValueSchema and KeyValue from pulsar-common module. This use
harms the code quality because it could lose the type safety.

Modifications

For the 1st issue, call another overload of Schema#KeyValue method and
note the default encoding type so that it's clear that the encoding
type of Schema#KeyValue(Schema<K>, Schema<V>) method is INLINE.

For the 2nd issue, leverage Java's type inference feature to make sure
the type arguments of KeyValue are the same as the type arguments of
KeyValueSchema in a TypedMessageBuilderImpl instane.
getKeyValueSchema method is added to simplify the code.

Verifying this change

  • Make sure that the change passes the CI checks.

This change is already covered by existing tests, such as SchemaTest and
NullValueTest in pulsar-broker module.

Documentation

Check the box below or label this PR directly.

Need to update docs?

  • doc-required
    (Your PR needs to update docs and you will update later)

  • doc-not-needed
    (Please explain why)

  • doc
    (Your PR contains doc changes)

  • doc-complete
    (Docs have been already added)

@BewareMyPower BewareMyPower added component/client-java type/refactor Code or documentation refactors. e.g. refactor code structure or methods to improve code readability labels Aug 24, 2022
@BewareMyPower BewareMyPower added this to the 2.12.0 milestone Aug 24, 2022
@BewareMyPower BewareMyPower self-assigned this Aug 24, 2022
@github-actions

github-actions Bot commented Sep 4, 2022

Copy link
Copy Markdown

@BewareMyPower Please provide a correct documentation label for your PR.
Instructions see Pulsar Documentation Label Guide.

…sages

### Motivation

First, it's hard to know the default encoding type of a KeyValue schema
from the API and its JavaDocs, see
https://github.com/apache/pulsar/blob/fd9489771959f3e722656e4b70d4bd891a13f690/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/Schema.java#L386-L391

The default encoding type could only be found in `KeyValueSchemaImpl#of`
method from another module (`pulsar-client`).

Second, there are much raw use of parameterized class, including
`KeyValueSchema` and `KeyValue` from `pulsar-common` module. This use
harms the code quality because it could lose the type safety.

### Modifications

For the 1st issue, call another overload of `Schema#KeyValue` method and
note the default encoding type so that it's clear that the encoding
type of `Schema#KeyValue(Schema<K>, Schema<V>)` method is `INLINE`.

For the 2nd issue, leverage Java's type inference feature to make sure
the type arguments of `KeyValue` are the same as the type arguments of
`KeyValueSchema` in a `TypedMessageBuilderImpl` instane.
`getKeyValueSchema` method is added to simplify the code.

### Verifying this change

- [ ] Make sure that the change passes the CI checks.

This change is already covered by existing tests, such as `SchemaTest` and
`NullValueTest` in `pulsar-broker` module.
@BewareMyPower
BewareMyPower force-pushed the bewaremypower/key-value-simplify branch from 1ab46fa to 9058334 Compare September 16, 2022 07:25
@BewareMyPower

Copy link
Copy Markdown
Contributor Author

@Demogorgon314 @codelipenghui @eolivelli @lhotari @gaoran10 Could you take a look?

msgMetadata.setNullPartitionKey(true);
return this;
}
getKeyValueSchema().ifPresent(keyValueSchema -> checkArgument(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While you're here, can you explain why when the schema is KeyValue, and the encoding is SEPARATED, it is forbidden to use this method to se the key of the message?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because when the encoding is SEPARATED, the partition key should be set by a KeyValue object.

Producer<KeyValue<String, String>> producer = client.newProducer(
                Schema.KeyValue(Schema.STRING, Schema.STRING, KeyValueEncodingType.SEPARATED))
        .topic("my-topic")
        .create();
producer.newMessage().value(new KeyValue<>("key", "value")).send()

With the SEPARATED key value encoding type, the code above will send a message whose partition key is "key" and value is "value". If it's allowed to set the partition key here, conflicts will happen.

There is no design of the key value schema, I just guessed the reason why key and keyBytes methods are forbidden and followed the previous behavior in this PR

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why.
Why can't we do

.newMessage() // this creates a builder
.key(theKey)
.value(theValue)
.send()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the schema type is Schema<KeyValue<K, V>>, the value's type must be KeyValue<K, V>, then the code will look like:

.key("key")
.value(new KeyValue<>("key-1", "value"))

The root cause is that Pulsar only stores the schema of the value. So it can only support key schema by passing a pair of "key" and "value" as the whole value.

@github-actions

github-actions Bot commented Nov 6, 2022

Copy link
Copy Markdown

The pr had no activity for 30 days, mark with Stale label.

@github-actions github-actions Bot added the Stale label Nov 6, 2022
@codelipenghui
codelipenghui merged commit 5d6a88e into apache:master Nov 16, 2022
@BewareMyPower
BewareMyPower deleted the bewaremypower/key-value-simplify branch November 16, 2022 01:57
congbobo184 pushed a commit that referenced this pull request Nov 17, 2022
@congbobo184 congbobo184 added the cherry-picked/branch-2.9 Archived: 2.9 is end of life label Nov 17, 2022
congbobo184 pushed a commit that referenced this pull request Dec 7, 2022
liangyepianzhou pushed a commit that referenced this pull request Dec 12, 2022
nicoloboschi pushed a commit to datastax/pulsar that referenced this pull request Jan 10, 2023
…sages (apache#17256)

(cherry picked from commit 5d6a88e)
(cherry picked from commit a8b00fd)
nicoloboschi pushed a commit to datastax/pulsar that referenced this pull request Jan 11, 2023
…sages (apache#17256)

(cherry picked from commit 5d6a88e)
(cherry picked from commit a8b00fd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants